package com.xuelang.pipeline.artifact.app.resource.impl;

import com.xuelang.hiforce.base.tracing.TracingUtils;
import com.xuelang.pipeline.artifact.app.harborv2.enums.MemberRoleIdEnum;
import com.xuelang.pipeline.artifact.app.resource.ArtifactUserService;
import com.xuelang.pipeline.artifact.app.resource.InstanceUserService;
import com.xuelang.pipeline.artifact.app.resource.converter.ArtifactUserDTOToArtifactUserConverter;
import com.xuelang.pipeline.artifact.client.common.constant.ArtifactConstant;
import com.xuelang.pipeline.artifact.client.common.constant.Constant;
import com.xuelang.pipeline.artifact.client.common.request.PageParam;
import com.xuelang.pipeline.artifact.client.common.result.PageRecord;
import com.xuelang.pipeline.artifact.client.common.util.BizAssert;
import com.xuelang.pipeline.artifact.client.common.util.PasswordUtil;
import com.xuelang.pipeline.artifact.client.resource.dto.ArtifactRoleUserDTO;
import com.xuelang.pipeline.artifact.client.resource.dto.ArtifactUserDTO;
import com.xuelang.pipeline.artifact.client.resource.dto.ArtifactUserQuery;
import com.xuelang.pipeline.artifact.client.resource.enums.ArtifactToolEnum;
import com.xuelang.pipeline.artifact.domain.resource.ArtifactTool;
import com.xuelang.pipeline.artifact.domain.resource.ArtifactUser;
import com.xuelang.pipeline.artifact.domain.resource.service.ArtifactToolDomainService;
import com.xuelang.pipeline.artifact.domain.resource.service.ArtifactUserDomainService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 仓库用户服务实现类
 *
 * @author xiwen.zxg
 * @since 2024/5/15
 */
@Service
public class ArtifactUserServiceImpl implements ArtifactUserService {

    @Autowired
    ArtifactUserDomainService artifactUserDomainService;
    @Autowired
    ArtifactToolDomainService artifactToolDomainService;
    @Autowired
    InstanceUserService instanceUserService;

    @Override
    public PageRecord<ArtifactUserDTO> pageList(PageParam<ArtifactUserQuery> dtoPageParam) {
        ArtifactUserQuery condition = dtoPageParam.getCondition();
        condition = condition == null ? new ArtifactUserQuery() : condition;
        PageRecord<ArtifactUser> pageRecord = artifactUserDomainService.pageList(
                dtoPageParam.getCurrentPage(),
                dtoPageParam.getPageSize(),
                condition);
        return new PageRecord<>(
                pageRecord.getCurrentPage(),
                pageRecord.getPageSize(),
                pageRecord.getTotalCount(),
                pageRecord.getTotalPages(),
                pageRecord.getRecords().stream().map(ArtifactUserDTOToArtifactUserConverter.INSTANCE::artifactUserToArtifactUserDTO).collect(Collectors.toList()));
    }

    @Override
    public List<ArtifactUserDTO> list(ArtifactUserQuery artifactUserQuery) {
        return artifactUserDomainService.list(artifactUserQuery).stream().map(ArtifactUserDTOToArtifactUserConverter.INSTANCE::artifactUserToArtifactUserDTO).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(ArtifactUserDTO artifactUserDTO) {
        ArtifactUser artifactUser = ArtifactUserDTOToArtifactUserConverter.INSTANCE.artifactUserDTOToArtifactUser(artifactUserDTO);
        artifactUser.setCreatorId(TracingUtils.getUserId());
        artifactUser.setUpdaterId(TracingUtils.getUserId());
        return artifactUserDomainService.save(artifactUser);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(ArtifactUserDTO artifactUserDTO) {
        BizAssert.notNull(artifactUserDTO.getId(), "id不能为空");
        ArtifactUser artifactUser = ArtifactUserDTOToArtifactUserConverter.INSTANCE.artifactUserDTOToArtifactUser(artifactUserDTO);
        artifactUser.setCreatorId(TracingUtils.getUserId());
        artifactUser.setUpdaterId(TracingUtils.getUserId());
        return artifactUserDomainService.update(artifactUser);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(String id) {
        BizAssert.notNull(id, "id不能为空");
        return artifactUserDomainService.delete(id);
    }


    @Override
    public ArtifactUserDTO query(String id) {
        BizAssert.notNull(id, "id不能为空");
        ArtifactUser artifactUser = artifactUserDomainService.query(id);
        return ArtifactUserDTOToArtifactUserConverter.INSTANCE.artifactUserToArtifactUserDTO(artifactUser);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateArtifactRoleUser(ArtifactRoleUserDTO artifactRoleUserDTO) {
        String artifactUuid = artifactRoleUserDTO.getArtifactUuid();
        String artifactType = artifactRoleUserDTO.getArtifactType();
        boolean isHarborRole = ArtifactToolEnum.ArtifactTypeEnum.getByKey(artifactType).equals(ArtifactToolEnum.ArtifactTypeEnum.DOCKER);
        List<ArtifactRoleUserDTO.BusinessUserVO> managerList = artifactRoleUserDTO.getManagerList();
        List<ArtifactRoleUserDTO.BusinessUserVO> developerList = artifactRoleUserDTO.getDeveloperList();
        List<ArtifactRoleUserDTO.BusinessUserVO> userList = artifactRoleUserDTO.getUserList();

        ArtifactTool artifactTool = artifactToolDomainService.query(artifactUuid);
        BizAssert.notNull(artifactTool, "仓库不存在");


        String instanceRepositoryName = artifactTool.getInstanceRepositoryName();

        List<ArtifactUser> artifactUserList =  new ArrayList<>();
        Optional.ofNullable(managerList).ifPresent(list -> managerList.forEach(manager ->
                artifactUserList.add(
                        ArtifactUser.builder()
                                .userName(manager.getUserName())
                                .userId(manager.getUserId())
                                .artifactRoleCode(ArtifactToolEnum.RoleEnum.MANAGER.name())
                                .artifactRoleId(isHarborRole ? MemberRoleIdEnum.MAINTAINER.getRoleId() : ArtifactConstant.ROLE_PREFIX_MANAGER + artifactTool.getInstanceRepositoryName())
                                // TODO: 此处拼接userId或者userName可能会过长或者出现重复，建议优化为缓存取唯一值短串做拼接
                                .artifactUserName(ArtifactConstant.USER_PREFIX_MANAGER + artifactTool.getInstanceRepositoryName() + Constant.DEFAULT_MIDDLE_SEPARATOR + manager.getUserName())
                                .artifactUserId(ArtifactConstant.USER_PREFIX_MANAGER + artifactTool.getInstanceRepositoryName() + Constant.DEFAULT_MIDDLE_SEPARATOR + manager.getUserId())
                                .artifactUserPassword(PasswordUtil.getStrongPassword())
                                .artifactType(artifactTool.getArtifactType())
                                .artifactUuid(artifactUuid)
                                .instanceRepositoryName(artifactTool.getInstanceRepositoryName())
                                .updaterId(TracingUtils.getUserId())
                                .creatorId(TracingUtils.getUserId())
                                .build()
                )
        ));
        Optional.ofNullable(developerList).ifPresent(list -> developerList.forEach(developer ->
                artifactUserList.add(
                        ArtifactUser.builder()
                                .userName(developer.getUserName())
                                .userId(developer.getUserId())
                                .artifactRoleCode(ArtifactToolEnum.RoleEnum.DEVELOPER.name())
                                .artifactRoleId(isHarborRole ? MemberRoleIdEnum.DEVELOPER.getRoleId() : ArtifactConstant.ROLE_PREFIX_DEVELOPER + artifactTool.getInstanceRepositoryName())
                                .artifactUserName(ArtifactConstant.USER_PREFIX_DEVELOPER + artifactTool.getInstanceRepositoryName() + Constant.DEFAULT_MIDDLE_SEPARATOR + developer.getUserName())
                                .artifactUserId(ArtifactConstant.USER_PREFIX_DEVELOPER + artifactTool.getInstanceRepositoryName() + Constant.DEFAULT_MIDDLE_SEPARATOR + developer.getUserId())
                                .artifactUserPassword(PasswordUtil.getStrongPassword())
                                .artifactType(artifactTool.getArtifactType())
                                .artifactUuid(artifactUuid)
                                .instanceRepositoryName(artifactTool.getInstanceRepositoryName())
                                .updaterId(TracingUtils.getUserId())
                                .creatorId(TracingUtils.getUserId())
                                .build()
                )
        ));
        Optional.ofNullable(userList).ifPresent(list -> userList.forEach(user ->
                artifactUserList.add(
                        ArtifactUser.builder()
                                .userName(user.getUserName())
                                .userId(user.getUserId())
                                .artifactRoleCode(ArtifactToolEnum.RoleEnum.USER.name())
                                .artifactRoleId(isHarborRole ? MemberRoleIdEnum.GUEST.getRoleId() : ArtifactConstant.ROLE_PREFIX_USER + artifactTool.getInstanceRepositoryName())
                                .artifactUserName(ArtifactConstant.USER_PREFIX_USER + artifactTool.getInstanceRepositoryName() + Constant.DEFAULT_MIDDLE_SEPARATOR + user.getUserName())
                                .artifactUserId(ArtifactConstant.USER_PREFIX_USER + artifactTool.getInstanceRepositoryName() + Constant.DEFAULT_MIDDLE_SEPARATOR + user.getUserId())
                                .artifactUserPassword(PasswordUtil.getStrongPassword())
                                .artifactType(artifactTool.getArtifactType())
                                .artifactUuid(artifactUuid)
                                .instanceRepositoryName(artifactTool.getInstanceRepositoryName())
                                .updaterId(TracingUtils.getUserId())
                                .creatorId(TracingUtils.getUserId())
                                .build()
                )
        ));
        List<ArtifactUser> originalUserList = artifactUserDomainService.list(ArtifactUserQuery.builder().artifactUuid(artifactUuid).build());
        if (!originalUserList.isEmpty()) {
            instanceUserService.deleteUserOfRepository(ArtifactToolEnum.ArtifactTypeEnum.getByKey(artifactType), originalUserList);
            artifactUserDomainService.deleteByArtifactUuid(artifactUuid);
        }
        if (!artifactUserList.isEmpty()) {
            instanceUserService.createUserOfRepository(ArtifactToolEnum.ArtifactTypeEnum.getByKey(artifactType), artifactUserList);
            artifactUserDomainService.batchInsertArtifactUser(artifactUserList);
        }
        return true;
    }

    @Override
    public ArtifactRoleUserDTO queryArtifactRoleUser(String artifactUuid) {
        ArtifactRoleUserDTO artifactRoleUserDTO = new ArtifactRoleUserDTO();
        artifactRoleUserDTO.setArtifactUuid(artifactUuid);
        artifactRoleUserDTO.setArtifactType(artifactToolDomainService.query(artifactUuid).getArtifactType());
        List<ArtifactUser> artifactUserList =  artifactUserDomainService.list(ArtifactUserQuery.builder().artifactUuid(artifactUuid).build());
        Optional.ofNullable(artifactUserList).ifPresent(list -> {
            //根据仓库角色标识ARTIFACT_ROLE_CODE过滤manager角色的列表
            artifactRoleUserDTO.setManagerList(
                    list.stream()
                            .filter(artifactUser -> artifactUser.getArtifactRoleCode().equals(ArtifactToolEnum.RoleEnum.MANAGER.name()))
                            .map(artifactUser -> ArtifactRoleUserDTO.BusinessUserVO.builder().userName(artifactUser.getUserName()).userId(artifactUser.getUserId()).build())
                            .collect(Collectors.toList())
            );
            //根据仓库角色标识ARTIFACT_ROLE_CODE过滤developer角色的列表
            artifactRoleUserDTO.setDeveloperList(
                    list.stream()
                            .filter(artifactUser -> artifactUser.getArtifactRoleCode().equals(ArtifactToolEnum.RoleEnum.DEVELOPER.name()))
                            .map(artifactUser -> ArtifactRoleUserDTO.BusinessUserVO.builder().userName(artifactUser.getUserName()).userId(artifactUser.getUserId()).build())
                            .collect(Collectors.toList())
            );
            //根据仓库角色标识ARTIFACT_ROLE_CODE过滤user角色的列表
            artifactRoleUserDTO.setUserList(
                    list.stream()
                            .filter(artifactUser -> artifactUser.getArtifactRoleCode().equals(ArtifactToolEnum.RoleEnum.USER.name()))
                            .map(artifactUser -> ArtifactRoleUserDTO.BusinessUserVO.builder().userName(artifactUser.getUserName()).userId(artifactUser.getUserId()).build())
                            .collect(Collectors.toList())
            );
        });
        return artifactRoleUserDTO;
    }


}
